package org.qm.maven.plugin;

import org.apache.maven.plugin.logging.Log;

import java.io.File;
import java.net.URL;
import java.net.URLClassLoader;
import java.util.HashSet;
import java.util.Set;

/**
 * @author daimao  Date: 15/9/18 Time: 下午2:51
 * @version $Id$
 */
public class PackageUtils {

    public static final String FILE_SEPARATOR = System.getProperties().getProperty("file.separator");

    public static Set<Class<?>> getClasses(File outputDir, String basePackage, Log log) throws Exception {
        String package2Path = parsePackage2Path(basePackage);
        File packageFile = new File(outputDir.getAbsolutePath() + FILE_SEPARATOR + package2Path);

        Set<Class<?>> classes = new HashSet<>();

        File[] files = packageFile.listFiles();

        log.info("start searching class in " + outputDir.getAbsolutePath());
        URLClassLoader classLoader = new URLClassLoader(new URL[] { outputDir.toURI().toURL() }, PackageUtils.class.getClassLoader());
        searchAndAdd(files, classes, basePackage, classLoader, log);
        return classes;
    }

    private static void searchAndAdd(File[] files, Set<Class<?>> classes, String basePackage,URLClassLoader classLoader, Log log) throws ClassNotFoundException {
        if (files == null || files.length == 0) {
            return;
        }
        for (File file : files) {
            String fileName = file.getName();
            if (file.isDirectory()) {
                searchAndAdd(file.listFiles(), classes, basePackage + "." + fileName, classLoader, log);
            } else {
                String thizzClass = basePackage + "." + fileName.substring(0, fileName.lastIndexOf("."));
                log.info("found file " + fileName + ", class:" + thizzClass);
                Class<?> clazz = classLoader.loadClass(thizzClass);
                if (clazz.isInterface()) {
                    classes.add(clazz);
                }
            }
        }
    }

    private static String parsePackage2Path(String basePackage) {
        return basePackage.replaceAll("\\.", FILE_SEPARATOR);
    }

}